// ## 2023/09/25 # 氕氘氚 # 重构 ##

namespace UNIT_ATTR
{
	const int 仲介修正比率 = 20;
	const int 血缘修正比率 = 20;
	const int 亲爱修正比率 = 15;
	const int 正常修正比率 = 10;

	const int 攻统占比 = 70;
	const int 攻武占比 = 30;
	const int 防统占比 = 70;
	const int 防智占比 = 30;
	const int 建设政治占比 = 70;
	const int 建设修正参数 = 50;
	const int 锻炼兵攻防倍率 = 110;
	const int 精锐兵攻防倍率 = 120;
	const int 剑兵攻防倍率 = 80;
	const int 走舸攻防倍率 = 80;
	const int 运输攻防倍率 = 50;
	const int 运输建设倍率 = 50;
	const int 混乱攻防倍率 = 80;

	const bool 部队气力修正 = true;
	const int 基准气力 = 150;     //一方面由于县城不能自动攻击,一方面防御力由于和耐久挂钩也很低,因此士气的加成保持满比例状态更平衡
	const float 气力修正系数 = 0.20;
	const bool 兵种地形修正 = true;
	const bool 骑兵攻击气力修正 = true;

	const bool 建筑光环修正 = true;
	const int 城市防御光环 = 30; //
	const int 港关防御光环 = 30; //
	const int 郡县防御光环 = 30;
	const int 阵防御光环 = 25;	 // 20点防御力大约是12%的伤害减免,  双倍的50点防御力大约是21%的伤害减免,
	const int 砦防御光环 = 25;	 // 25点防御力大约是16%的伤害减免,  双倍的50点防御力大约是27%的伤害减免,
	const int 城塞防御光环 = 30; // 30点防御力大约是19%的伤害减免,  双倍的60点防御力大约是35%的伤害减免,

	const int 精锐步兵加移 = 3;
	const int 良马产出加移 = 3;
	const int 精锐骑兵加移 = 3;
	const int 車轴强化加移 = 6;
	const int 木牛流马加移 = 8;
	const int 运输队加移 = 8;

	const bool 移动力_兵力影响 = true;
	const bool 移动力_适性影响 = true;
	const bool 移动力_统率影响 = true;
	const bool 移动力_气力影响 = true;
	const bool 移动力_季节影响 = true;
	const bool 移动力_领土影响 = true;

	const int 初级电脑建设倍率 = 95;
	const int 上级电脑建设倍率 = 105;
	const int 超级电脑建设倍率 = 120;


	class Main
	{
		Main()
		{
			pk::set_func(163, pk::func163_t(callback));
		}

		void callback(pk::unit_attr& attr, const pk::detail::arrayptr<pk::person @>& in member, int weapon_id, uint troops, int type, int status, bool navy, bool shoubyou)
		{
			pk::list<pk::person @> member_list;
			for (int i = 0; i < member.length; i++)
			{
				member_list.add(member[i]);
			}
			cal_unit_attr_t(attr, member_list, weapon_id, troops, type, status, navy, shoubyou);
		}

		void cal_unit_attr_t(pk::unit_attr& attr, pk::list<pk::person @> member, int weapon_id, uint troops, int type, int status, bool navy, bool shoubyou)
		{
			if (!pk::is_valid_equipment_id(weapon_id) or !pk::is_valid_unit_type(type) or !pk::is_valid_unit_status(status))
				return;

			pk::person @leader = member[0];
			if (!pk::is_alive(leader))
				return;

			pk::force @force = pk::get_force(leader.get_force_id());
			if (!pk::is_alive(force))
				return;

			// 部队指针和部队气力
			pk::unit @unit;
			int unit_energy = 0;
			pk::building @building = pk::hex_object_to_building(pk::get_hex_object(leader.location));
			if (pk::is_alive(building)) // 主将如果所属在某一建筑，则出征时使用建筑物的气力
			{
				unit_energy = pk::get_energy(building);
			}
			else
			{
				@unit = pk::get_unit(pk::get_unit_id(leader));
				unit_energy = unit.energy;
			}

			// 如果沒有副将
			if ((member[1] is null) and (member[2] is null))
			{
				for (int i = 0; i < 武将能力_末; i++) // 只发揮其主将能力
					attr.stat[i] = shoubyou ? leader.stat[i] : leader.max_stat[i];
			}
			// 有副将
			else
			{
				// 如果有厌恶关系则不进行修正
				if (is_dislike(leader, member[1]) or is_dislike(leader, member[2]) or is_dislike(member[1], member[2]))
				{
					for (int i = 0; i < 武将能力_末; i++)
						attr.stat[i] = shoubyou ? leader.stat[i] : leader.max_stat[i];
				}
				// 无厌恶关系时进行能力修正
				else
				{
					for (int i = 0; i < 武将能力_末; i++)
					{
						int a = 0, b = 0;
						int leader_stat = shoubyou ? leader.stat[i] : leader.max_stat[i];

						// 统率武力按武将关系修正
						if (i <= 武将能力_武力)
						{
							// 新的修飾方式：主将+副将1修正+副将2修正
							if (member[1] !is null)
								a = func_sub_stat(leader, member[1], (shoubyou ? member[1].stat[i] : member[1].max_stat[i]));
							if (member[2] !is null)
								b = func_sub_stat(leader, member[2], (shoubyou ? member[2].stat[i] : member[2].max_stat[i]));
							attr.stat[i] = pk::min(255, (leader_stat + a + b));
						}

						// 智力政治魅力取最大值
						else
						{
							int max_value = leader_stat;
							if (member[1] !is null)
								max_value = pk::max(max_value, shoubyou ? member[1].stat[i] : member[1].max_stat[i]);
							if (member[2] !is null)
								max_value = pk::max(max_value, shoubyou ? member[2].stat[i] : member[2].max_stat[i]);
							attr.stat[i] = max_value;
						}
					}
				}
			}

			// 适性取最大值
			for (int i = 0; i < 兵种_末; i++)
			{
				int max_value = 0;
				for (int j = 0; j < member.count; j++)
				{
					if (member[j] !is null)
						max_value = pk::max(max_value, member[j].tekisei[i]);
				}
				attr.tekisei[i] = max_value;
			}

			// 攻防建 ==========================================================================================================

			// 兵器能力
			pk::equipment @equipment = pk::get_equipment(weapon_id);

			float atk;
			float def;
			float con = 0.f;																								 // 建设
			float co_tekisei = float(pk::core["tekisei"][attr.tekisei[pk::equipment_id_to_heishu(weapon_id)]]["unit_stat"]); // 能力倍率
			float co_ad = 1.f;																								 // 攻防系数
			float co_con = 1.f;																								 // 建造系数

			if (weapon_id == 兵器_剑)
				co_ad = 剑兵攻防倍率 / 100.f;

			//由于走舸已经给了很低基础攻防,不需要再给系数了.会导致剧本的攻防值产生困惑.
			// if (weapon_id == 兵器_走舸)
			// 	co_ad = 走舸攻防倍率 / 100.f;

			if (status == 部队状态_混乱)
				co_ad = 混乱攻防倍率 / 100.f;
			if (type == 部队类型_运输)
			{
				co_ad = 运输攻防倍率 / 100.f;
				co_con = 运输建设倍率 / 100.f;
			}

			// 攻防保底(基础值)的意义是为了伤害的指数函数计算的时候,避免数字太小而导致极端值.
			// 基础攻防值是为了在武将属性低的时候增强兵种特性.(由于大部分武将属性偏差,因此乘法系数太小几乎无影响,因此增加了兵种保底来优化曲线)
			int basic_atk = (equipment.stat[兵器能力_攻击]);
			int basic_def = (equipment.stat[兵器能力_防御]);
			int 适性加成 = int((co_tekisei - 0.6) * 100);
			//if (navy) 适性加成 = 适性加成 + 10;  //水军C实在太多,水战也比较频繁,因此略微提高下限
			int 水军保底修正 = 20;

			float person_atk = (攻武占比 / 100.f * attr.stat[部队能力_武力] + 攻统占比 / 100.f * attr.stat[部队能力_统率] + 适性加成);
			float person_def = (防智占比 / 100.f * attr.stat[部队能力_智力] + 防统占比 / 100.f * attr.stat[部队能力_统率] + 适性加成);

			atk = (person_atk * basic_atk * 0.8 + (basic_atk - 50) * 0.2) / 100;
			def = (person_def * basic_def * 0.8 + (basic_def - 50) * 0.2) / 100;

		  //由于本作水系较多,水军走舸系数又太低,因此为了适配高统帅低适性的武将,用不同算法(避免曹操下水只有30防御的情况)
		  //同时也减少了水军的方差,提高了水军下限.
			if (navy)
			{
				atk = atk * 0.9 + 水军保底修正;
				def = def * 0.9 + 水军保底修正;
			}

			if (navy and 科技加强包::开启_科技加强包)
			{

				atk = atk + 10;
				def = def + 10;
			}


			atk = atk * co_ad;
			def = def * co_ad;

			con = (建设政治占比 / 100.f * attr.stat[部队能力_政治] + 建设修正参数) * co_con;


			con *= (leader.is_player() ? 100 : con_difficulty_impact()) / 100.f;

			if (!leader.is_player()) con = con * 120 / 100;

			// pk::trace(pk::format("兵种基础攻击 :{},co_tekisei:{}", basic_atk, basic_def));

			// 技巧加成
			int 锻炼技巧 = -1, 精锐技巧 = -1;
			if (weapon_id == 兵器_枪)
			{
				锻炼技巧 = 技巧_枪兵锻练;
				精锐技巧 = 技巧_精锐枪兵;
			}
			else if (weapon_id == 兵器_戟)
			{
				锻炼技巧 = 技巧_戟兵锻练;
				精锐技巧 = 技巧_精锐戟兵;
			}
			else if (weapon_id == 兵器_弩)
			{
				锻炼技巧 = 技巧_弩兵锻练;
				精锐技巧 = 技巧_精锐弩兵;
			}
			else if (weapon_id == 兵器_战马)
			{
				锻炼技巧 = 技巧_骑兵锻练;
				精锐技巧 = 技巧_精锐骑兵;
			}
			if (pk::has_tech(force, 精锐技巧))
			{
				atk *= 精锐兵攻防倍率 / 100.f;
				def *= 精锐兵攻防倍率 / 100.f;
			}
			else if (pk::has_tech(force, 锻炼技巧))
			{
				atk *= 锻炼兵攻防倍率 / 100.f;
				def *= 锻炼兵攻防倍率 / 100.f;
			}

			// 气力修正
			int max_energy = ch::get_max_energy(pk::has_tech(force, 技巧_熟练兵));
			atk *= energy_impact_ratio(unit_energy, max_energy);
			def *= energy_impact_ratio(unit_energy, max_energy);

			// 骑兵气力增强
			if (weapon_id == 兵器_战马 and 骑兵攻击气力修正)
				atk *= pk::max(1.0, 1.0 + float((unit_energy - 80) / 100));

			// 特技加成
			if (weapon_id == 兵器_戟 && ch::has_skill(member, 特技_重甲))
			{
				def = def + pk::core::skill_constant_value(特技_重甲, 0);
			}
			if (weapon_id >= 兵器_冲车 && weapon_id <= 兵器_木兽 && ch::has_skill(member, 特技_重器))
			{
				def = int(def * (100 + pk::core::skill_constant_value(特技_重器)) / 100.f);
			}

			// 移动力 ==========================================================================================================
			int mov = equipment.stat[兵器能力_移动];
			float mov_var = mov;

			if (weapon_id <= 兵器_弩 and city_tech::is_force_has_city(force, 16) and city_tech::is_atk_unit(unit))
			{
				mov_var = mov_var * 1.1f;
			}
			// 兵力影响
			if (移动力_兵力影响)
			{
				if (type == 部队类型_运输)
					mov_var = mov_var + 1 - pk::min(5, (troops / 6000));
				else
					mov_var = mov_var + 1 - pk::min(10, (troops / 3000));
			}
			// 适性影响
			if (移动力_适性影响)
			{
				if (type == 部队类型_战斗)
					mov_var = mov_var * (1.05f + 0.02f * pk::min(2, (attr.tekisei[pk::equipment_id_to_heishu(weapon_id)] - 适性_A)));
			}
			// 统率影响
			if (移动力_统率影响)
				mov_var = mov_var * (0.95f + 0.05f * (leader.stat[武将能力_统率] / 100.f));
			// 气力影响
			if (移动力_气力影响)
				mov_var = mov_var * (0.95 + 0.05f * (unit_energy / 120.f));
			// 季节影响
			if (移动力_季节影响 and !navy) // 改成只影响陆军好了，否则对水军影响过大
			{
				switch (pk::get_season())
				{
					case 季节_春:
						mov_var += 2;
						break;
					case 季节_秋:
						mov_var += 2;
						break;
					case 季节_夏:
						mov_var -= 0;
						break;
					case 季节_冬:
						mov_var -= 2;
						break;
				}
			}
			// 领土影响
			if (移动力_领土影响 and pk::is_alive(unit))
			{
				pk::building @area_building = pk::get_building(pk::get_building_id(unit.pos));
				if (pk::is_alive(area_building))
				{
					if (unit.get_force_id() == area_building.get_force_id())
						mov_var = mov_var * 1.1f; // 友军领土
					else if (pk::is_enemy(unit, area_building))
						mov_var = mov_var * 0.9f; // 敌军领土
				}
			}
			// 状态影响
			if (unit !is null && unit.status == 部队状态_恐惧)
				mov_var /= 2.f;

			mov = int(mov_var);

			// 技巧加成
			switch (weapon_id)
			{
				case 兵器_枪:
					if (pk::has_tech(force, 技巧_精锐枪兵))
						mov = mov + 精锐步兵加移;
					break;
				case 兵器_戟:
					if (pk::has_tech(force, 技巧_精锐戟兵))
						mov = mov + 精锐步兵加移;
					if (unit !is null and city_tech::is_force_has_city(force, 41) and pk::get_hex(unit.get_pos()).terrain == 地形_森)
					{
						mov = mov + 5;
						atk = atk * 1.2f;
						def = def * 1.2f;
					}
					break;
				case 兵器_弩:
					if (pk::has_tech(force, 技巧_精锐弩兵))
						mov = mov + 精锐步兵加移;
					break;
				case 兵器_战马:
					if (pk::has_tech(force, 技巧_良马产出))
						mov = mov + 良马产出加移;
						if (pk::has_tech(force, 技巧_良马产出))
						def = def + 10;

					if (pk::has_tech(force, 技巧_精锐骑兵))
						mov = mov + 精锐骑兵加移;
					if (city_tech::is_force_has_city(force, 18))
						mov = mov + 3;
					if (city_tech::is_force_has_city(force, 18))
						atk = atk * 1.05;
					if (city_tech::is_force_has_city(force, 0) and !city_tech::is_atk_unit(unit))
						def = def * 1.15;
					break;
				case 兵器_冲车:
				case 兵器_井阑:
				case 兵器_投石:
				case 兵器_木兽:
					if (pk::has_tech(force, 技巧_车轴强化))
						mov = mov + 車轴强化加移;
					if (city_tech::is_force_has_city(force, 11))
						def = def * 1.1;
					break;
			}

			// 特技加成
			if (weapon_id <= 兵器_弩)
			{
				mov = mov + (ch::has_skill(member, 特技_强行) ? pk::core::skill_constant_value(特技_强行) : 0);
			}
			else if (weapon_id == 兵器_战马)
			{
				int a_强行 = ch::has_skill(member, 特技_强行) ? pk::core::skill_constant_value(特技_强行) : 0;
				int a_长驱 = ch::has_skill(member, 特技_长驱) ? pk::core::skill_constant_value(特技_长驱) : 0;
				mov = mov + pk::max(a_长驱, a_强行);
				if (ch::has_skill(member, 特技_铁骑))
				{
					float buff = (100 + pk::core::skill_constant_value(特技_铁骑)) / 100.f;
					atk = atk * buff;
					def = def * buff;
				}
			}
			if (weapon_id == 兵器_枪)
			{
				if (ch::has_skill(member, 特技_枪锋))
				{
					float buff = (100 + pk::core::skill_constant_value(特技_枪锋)) / 100.f;
					atk = atk * buff;
					def = def * buff;
				}
				if (ch::has_skill(member, 特技_枪速))
				{
					float buff = (100 + pk::core::skill_constant_value(特技_枪速)) / 100.f;
					mov = int(mov * buff);
				}

				if (city_tech::is_force_has_city(force, 24))
					atk = atk * 1.05f;
			}

			if (weapon_id == 兵器_戟)
			{
				if (ch::has_skill(member, 特技_戟刃))
				{
					float buff = (100 + pk::core::skill_constant_value(特技_戟刃)) / 100.f;
					atk = atk * buff;
					def = def * buff;
				}
				if (ch::has_skill(member, 特技_戟舞))
				{
					float buff = (100 + pk::core::skill_constant_value(特技_戟舞)) / 100.f;
					mov = int(mov * buff);
				}
				if (ch::has_skill(member, 特技_重甲))
				{
					mov = mov - pk::core::skill_constant_value(特技_重甲, 2);
				}

				if (city_tech::is_force_has_city(force, 3))
					def = def * 1.08f;
			}
			if (weapon_id == 兵器_弩)
			{
				if (ch::has_skill(member, 特技_箭芒))
				{
					float buff = (100 + pk::core::skill_constant_value(特技_箭芒)) / 100.f;
					atk = atk * buff;
					def = def * buff;
				}
				if (ch::has_skill(member, 特技_箭痕))
				{
					float buff = (100 + pk::core::skill_constant_value(特技_箭痕)) / 100.f;
					mov = int(mov * buff);
				}

				if (city_tech::is_force_has_city(force, 25))
					atk = atk * 1.05f;
			}
			if (weapon_id >= 兵器_冲车 and weapon_id <= 兵器_木兽)
			{
				if (ch::has_skill(member, 特技_能工))
				{
					float buff = (100 + pk::core::skill_constant_value(特技_能工)) / 100.f;
					atk = atk * buff;
					def = def * buff;
				}
			}
			// 水军
			if (navy)
			{
				if (ch::has_skill(member, 特技_操舵))
					mov = mov + pk::core::skill_constant_value(特技_操舵);

				if (city_tech::is_force_has_city(force, 23))
					atk = atk * 1.08f;

				if (city_tech::is_force_has_city(force, 27))
					def = def * 1.1f;

				if (city_tech::is_force_has_city(force, 31))
					mov = mov + 3;
			}

			if (unit !is null and (ch::has_skill(unit, 特技_阵势) or ch::has_skill(unit, 特技_幕帘)))
			{
				bool 阵势效果 = false;
				bool 幕帘效果 = false;
				array<pk::point> rings = pk::range(unit.get_pos(), 1, 1);
				for (int i = 0; i < int(rings.length); i++)
				{
					pk::unit@ dst = pk::get_unit(rings[i]);
					if (dst !is null and pk::is_alive(dst) and dst.get_force_id() == unit.get_force_id())
					{
						阵势效果 = true;
						幕帘效果 = true;
						break;
					}
				}
				if (阵势效果) atk = atk + pk::core::skill_constant_value(特技_阵势);
				if (幕帘效果) def = def + pk::core::skill_constant_value(特技_幕帘);
			}

			if (ch::has_skill(leader, 特技_良将))
			{
				int buff = pk::core::skill_constant_value(特技_良将);
				atk += buff;
				def += buff;
			}

			if ((member[1] !is null and ch::has_skill(member, 特技_良将)) or (member[2] !is null and ch::has_skill(member, 特技_良将)))
			{
				int buff = pk::core::skill_constant_value(特技_良将, 1);
				atk += buff;
				def += buff;
			}

			if (ch::has_skill(member, 特技_轻狂))
			{
				if (unit_energy >= max_energy / 2) atk += pk::core::skill_constant_value(特技_轻狂, 0);
				else atk -= pk::core::skill_constant_value(特技_轻狂, 1);

			}

			if (unit !is null and ch::has_skill(unit, 特技_轻辎) and int(unit.food) < int(unit.troops * 2))
			{
				mov += pk::core::skill_constant_value(特技_轻辎, 0);;
			}

			// 运输队加成
			if (type == 部队类型_运输)
			{
				mov = mov + 运输队加移;
				if (pk::has_tech(force, 技巧_木牛流马))
					mov = mov + 木牛流马加移;
				if (ch::has_skill(member, 特技_搬运))
					mov = mov + pk::core::skill_constant_value(特技_搬运);
			}

			// 保存 ==========================================================================================================
			attr.stat[部队能力_攻击] = pk::min(255, pk::max(1, int(atk)));
			attr.stat[部队能力_防御] = pk::min(255, pk::max(1, int(def)));
			attr.stat[部队能力_建设] = pk::min(255, pk::max(1, int(con)));
			attr.stat[部队能力_移动] = pk::min(50, pk::max(5, int(mov)));
		}

		pk::int_int get_unit_additional_atk_def_t(pk::unit @unit)
		{
			if (unit is null)
				return pk::int_int(0, 0);
			float atk = 0.f, def = 0.f;

			// 地形修正
			if (兵种地形修正)
			{
				pk::int_int tuple = terrain_impact(unit);
				atk += tuple.first;
				def += tuple.second;
			}

			// 建筑光环加成
			if (建筑光环修正)
			{
				if (unit.weapon == 兵器_戟)
					def += int(defence_building_impact(unit) * 2.0);
				else
					def += int(defence_building_impact(unit) * 1.0);
			}

			// 友军光环加成
			int halo_buff = halo_impact(unit);
			atk += halo_buff;
			def += halo_buff;

			if (has_atk_buff_building(unit.pos, unit.get_force_id()))
			{
				atk += unit.attr.stat[部队能力_攻击] * 0.1f;
			}

			return pk::int_int(int(atk), int(def));
		}

		bool is_dislike(pk::person @a, pk::person @b)
		{
			if (a !is null and b !is null)
				return pk::is_dislike(a, b.get_id()) or pk::is_dislike(b, a.get_id());
			return false;
		}

		// 副将能力修正 关系
		int func_sub_stat(pk::person @leader, pk::person @deputy, int deputy_stat)
		{
			int leader_id = leader.get_id();
			int deputy_id = deputy.get_id();

			int stat_add = 0;

			// 厌恶
			if (pk::is_dislike(leader, deputy_id) or pk::is_dislike(deputy, leader_id))
				stat_add = 0;
			// 仲介
			else if (pk::is_gikyoudai(leader, deputy_id) or pk::is_fuufu(leader, deputy_id))
				stat_add = int(仲介修正比率 / 100.f * deputy_stat);
			// 血缘，添加父母子女关系
			else if (pk::is_ketsuen(leader, deputy_id) or pk::is_oyako(leader, deputy_id))
				stat_add = int(血缘修正比率 / 100.f * deputy_stat);
			// 亲爱
			else if (pk::is_like(leader, deputy_id) or pk::is_like(deputy, leader_id))
				stat_add = int(亲爱修正比率 / 100.f * deputy_stat);
			// 其他
			else
				stat_add = int(正常修正比率 / 100.f * deputy_stat);

			return stat_add;
		}
		// --------------------------------------------------------------------------------------

		// 修正：地形
		pk::int_int terrain_impact(pk::unit @unit)
		{
			int weapon_id = unit.weapon;
			pk::hex @unit_hex = pk::get_hex(unit.get_pos());
			switch (unit_hex.terrain)
			{
				case 地形_草地:
					if (weapon_id == 兵器_战马)
						return pk::int_int(30, 0);
					break;
				case 地形_砂地:
					if (weapon_id == 兵器_枪)
						return pk::int_int(5, 0);
					else if (weapon_id == 兵器_战马)
						return pk::int_int(30, 0);
					break;
				case 地形_湿地:
					if (weapon_id == 兵器_枪)
						return pk::int_int(5, 0);
					else if (weapon_id == 兵器_戟)
						return pk::int_int(0, 10);
					else if (weapon_id == 兵器_弩)
						return pk::int_int(-5, 0);
					else if (weapon_id == 兵器_战马)
						return pk::int_int(-30, 0);
					break;
				case 地形_毒泉:
					if (weapon_id == 兵器_枪)
						return pk::int_int(-10, 0);
					else if (weapon_id == 兵器_戟)
						return pk::int_int(-10, 10);
					else if (weapon_id == 兵器_弩)
						return pk::int_int(-10, 0);
					else if (weapon_id == 兵器_战马)
						return pk::int_int(-20, 0);
					break;
				case 地形_森:
					if (weapon_id == 兵器_枪)
						return pk::int_int(10, 10);
					else if (weapon_id == 兵器_戟)
						return pk::int_int(0, 20);
					else if (weapon_id == 兵器_弩)
						return pk::int_int(-20, 10);
					else if (weapon_id == 兵器_战马)
						return pk::int_int(-30, 10);
					break;
				case 地形_荒地:
					if (weapon_id == 兵器_枪)
						return pk::int_int(0, 0);
					else if (weapon_id == 兵器_战马)
						return pk::int_int(30, 0);
					break;
				case 地形_官道:
					if (weapon_id == 兵器_枪)
						return pk::int_int(5, 0);
					else if (weapon_id == 兵器_戟)
						return pk::int_int(5, 0);
					else if (weapon_id == 兵器_弩)
						return pk::int_int(5, 0);
					else if (weapon_id == 兵器_战马)
						return pk::int_int(20, 0);
					break;
				case 地形_山:
					if (weapon_id == 兵器_枪)
						return pk::int_int(-10, 10);
					else if (weapon_id == 兵器_戟)
						return pk::int_int(-10, 10);
					else if (weapon_id == 兵器_弩)
						return pk::int_int(0, 10);
					else if (weapon_id == 兵器_战马)
						return pk::int_int(-30, 0);
					break;
			}
			return pk::int_int(0, 0);
		}

		// 防御修正：防御设施
		int defence_building_impact(pk::unit @unit)
		{
			int best_buff = get_best_def_buff(unit.get_pos(), unit.get_force_id());
			if (city_tech::is_unit_force_has_city(unit, 35))
				best_buff = best_buff + 10;
			return best_buff;
		}

		// 筛选范围内最佳防御建筑 （代替func_5aedc0）
		int get_best_def_buff(const pk::point& in pos, int force_id)
		{
			// 遍历2格内建筑(23.9.29起防御光环全部定为2格)，分别确认是否生效，获取最强buff，如果确认已找到最强，直接break
			array<pk::point> range = pk::range(pos, 1, 2);
			int buff, best_buff = 0;
			for (int i = 0; i < int(range.length); i++)
			{
				pk::building @building = pk::get_building(range[i]);
				if (pk::is_alive(building) && building.completed && building.get_force_id() == force_id)
				{
					switch (building.facility)
					{
						case 设施_城市:
							buff = 城市防御光环;
							break;
						case 设施_关卡:
						case 设施_港口:
							buff = 港关防御光环;
							break;
						case 设施_阵:
							buff = 阵防御光环;
							break;
						case 设施_砦:
							buff = 砦防御光环;
							break;
						case 设施_城塞:
							if (ch::is_valid_spec_id(ch::get_spec_id(building)) and ch::get_spec_p(ch::to_spec_id(building.get_id())).troops > 0)
								buff = 郡县防御光环;
							else
								buff = 城塞防御光环;
							break;
						default:
							buff = 0;
							break;
					}
					if (buff > best_buff)
					{
						best_buff = buff;
					}
				}
			}
			return best_buff;
		}

		// 攻防修正：友军光环
		int halo_impact(pk::unit @unit)
		{
			if (基础光环)
			{
				int halo_unit_id = halo::func_get_highest_halo(unit, 0);
				if (halo_unit_id != -1)
				{
					pk::unit @halo_unit = pk::get_unit(halo_unit_id);
					return halo::func_光环效果(halo_unit, 0);
				}
			}
			return 0;
		}

		// 攻防修正：气力
		// 修正范围是80%-100%
		float energy_impact_ratio(int energy, int max)
		{
			// 特技影响
			return 部队气力修正 ? (0.8 + (energy / float(max) * 气力修正系数)) : 1.f;
		}

	}

	Main main;

	// 计算守军属性
	void get_base_unit_attr(pk::building @building, int& out base_atk, int& out base_def, int& out base_troops)
	{
		pk::person @leader;
		int building_energy;
		float atk, def, troops;
		float basic_atk, basic_def;
		int max_energy = 100;

		specialinfo @spec_t = ch::get_spec_info(building);
		if (spec_t is null) // 城港关
		{
			pk::person @taishu = pk::get_person(pk::get_taishu_id(building));
			if (pk::is_alive(taishu))
				@leader = @taishu;
			troops = pk::get_troops(building);
			building_energy = pk::get_energy(building);
			max_energy = ch::get_max_energy(pk::has_tech(building, 技巧_熟练兵));
		}
		else // 府
		{
			if (spec_t.person >= 0)
				@leader = pk::get_person(spec_t.person);
			troops = spec_t.troops;
			building_energy = 基准气力;
			max_energy = 基准气力;

		}

		if (leader !is null)
		{
			// 不再调用剑兵数值,避免那天修改剑兵属性的时候把城市的属性也改了,到时候也很难找到
			// pk::equipment@ equipment = pk::get_equipment(兵器_剑);
			// atk = equipment.stat[兵器能力_攻击];
			// def = equipment.stat[兵器能力_防御];

			// 由于太守无法指定,AI的太守往往又是文官.因此城市攻防要尽量让太守占比足够低.
			basic_atk = (攻武占比 / 100.f * leader.stat[武将能力_武力] + 攻统占比 / 100.f * leader.stat[武将能力_统率]) * 0.2 + 150;
			basic_def = (防智占比 / 100.f * leader.stat[武将能力_智力] + 防统占比 / 100.f * leader.stat[武将能力_统率]) * 0.2 + 150;
		}
		else
		{
			basic_atk = 120.f;
			basic_def = 120.f;
		}

		// 城防修正
		int base_id = building.get_id();
		int city_defense = 0;
		if (pk::is_valid_base_id(base_id))
		{
			auto building_p = ch::get_baseIA(base_id);
			city_defense = building_p.city_defense;
		}

		//城防最多可以提供100点防御,增加3000打底值
		int total_defense = (pk::min(building.hp, 12000) + 3000) / 75;

		// 此处用120而不是max,是为了提高士气特别高的时候城市的攻击曲线
		atk = (basic_atk) * (0.3 + (pk::min(building_energy / 120.0, 1.0) * 0.7));

		// 此处用120而不是max,是为了不让初期面对150士气的时候,玩家感受到城市太难打,后期由于士气都满了,城防也会相对高一点
		def = (basic_def + total_defense) * (0.3 + (pk::min(building_energy / 120.0, 1.0) * 0.7));

		// 由于关隘耐久极高,而且具有最高的高度,因此具有很高的攻击防御,而且关隘不会被合围,因此关隘的自动攻击伤害威胁巨大,因此大幅削减关隘攻击力
		if (ch::is_gate(building.get_id()))
			atk /= 3;

		base_atk = pk::max(1, int(atk));
		base_def = pk::max(1, int(def));
		base_troops = int(troops);
	}

	void cal_unit_attr(pk::unit_attr& attr, pk::list<pk::person @> member, int weapon_id, uint troops, int type, int status, bool navy, bool shoubyou)
	{
		main.cal_unit_attr_t(attr, member, weapon_id, troops, type, status, navy, shoubyou);
	}

	void cal_unit_attr(pk::unit_attr& attr, pk::unit @unit)
	{
		pk::list<pk::person @> member_list;
		for (int i = 0; i < 3; i++)
		{
			int person_id = unit.member[i];
			if (pk::is_valid_person_id(person_id))
			{
				pk::person @person = pk::get_person(person_id);
				member_list.add(person);
			}
			else
				member_list.add(null);
		}
		bool navy = pk::is_in_water(unit);
		main.cal_unit_attr_t(attr, member_list, unit.weapon, unit.troops, unit.type, unit.status, navy, false);
	}

	// 太鼓台buff
	bool has_atk_buff_building(const pk::point& in pos, int force_id)
	{
		array<pk::point> range = pk::range(pos, 1, 3);
		for (int i = 0; i < int(range.length); i++)
		{
			pk::building @building = pk::get_building(range[i]);
			if (pk::is_alive(building) and building.completed and building.get_force_id() == force_id and building.facility == 设施_太鼓台)
			{
				return true;
			}
		}
		return false;
	}

	// 难度的伤害倍率加成
	int con_difficulty_impact()
	{
		int 难度加成 = 0;
		switch (pk::get_scenario().difficulty)
		{
			case 难易度_初级:

				难度加成 = 初级电脑建设倍率;
				break;
			case 难易度_上级:

				难度加成 = 上级电脑建设倍率;
				break;

			case 难易度_超级:

				难度加成 = 超级电脑建设倍率;
				break;
		}
		return 难度加成;
	}


	pk::int_int get_unit_additional_atk_def(pk::unit @unit)
	{
		return main.get_unit_additional_atk_def_t(unit);
	}
}
